package com.google.code.jerseyclients.httpclientfour;

/*
 * Olivier Lamy
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import javax.ws.rs.ext.Providers;

import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

import com.google.code.jerseyclients.JerseyHttpClientConfig;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;

/**
 * @author <a href="mailto:olamy@apache.org">Olivier Lamy</a>
 * @version $Id: ApacheHttpClientFour.java 8 2010-11-04 17:33:00Z oliver.lamy@gmail.com $
 */
public class ApacheHttpClientFour
    extends Client
{
    private ApacheHttpClientFourHandler clientHandler;

    /**
     * Create a new client instance.
     * 
     * @param root the root client handler
     */
    public ApacheHttpClientFour( ApacheHttpClientFourHandler root )
    {
        this( root, new DefaultClientConfig(), null );
    }

    /**
     * Create a new client instance with a client configuration.
     * 
     * @param root the root client handler
     * @param config the client configuration.
     */
    public ApacheHttpClientFour( ApacheHttpClientFourHandler root, ClientConfig config )
    {
        this( root, config, null );
    }

    /**
     * Create a new instance with a client configuration and a component provider.
     * 
     * @param root the root client handler
     * @param config the client configuration.
     * @param provider the IoC component provider factory.
     */
    public ApacheHttpClientFour( ApacheHttpClientFourHandler root, ClientConfig config,
                                 IoCComponentProviderFactory provider )
    {
        super( root, config, provider );
        this.clientHandler = root;
    }

    /**
     * Get the Apache HTTP client handler.
     * 
     * @return the Apache HTTP client handler.
     */
    public ApacheHttpClientFourHandler getClientHandler()
    {
        return clientHandler;
    }

    /**
     * Create a default client.
     * 
     * @return a default client.
     */
    public static ApacheHttpClientFour create( JerseyHttpClientConfig config,
                                               ThreadSafeClientConnManager threadSafeClientConnManager )
    {
        return new ApacheHttpClientFour( createDefaultClientHander( config, threadSafeClientConnManager ) );
    }

    /**
     * Create a default client with client configuration and component provider.
     * 
     * @param cc the client configuration.
     * @param provider the IoC component provider factory.
     * @return a default client.
     */
    protected static ApacheHttpClientFour create( ClientConfig cc, IoCComponentProviderFactory provider,
                                                  JerseyHttpClientConfig config )
    {
        return new ApacheHttpClientFour( createDefaultClientHander( config, null ), cc, provider );
    }

    /**
     * Create a default Apache HTTP client handler.
     * 
     * @return a default Apache HTTP client handler.
     */
    private static ApacheHttpClientFourHandler createDefaultClientHander(
                                                                          JerseyHttpClientConfig config,
                                                                          ThreadSafeClientConnManager threadSafeClientConnManager )
    {

        if ( threadSafeClientConnManager == null )
        {
            throw new IllegalArgumentException( "threadSafeClientConnManager cannot be null" );
        }

        HttpParams httpParams = new BasicHttpParams();

        HttpProtocolParams.setVersion( httpParams, HttpVersion.HTTP_1_1 );
        HttpClient client = new DefaultHttpClient( threadSafeClientConnManager, httpParams );

        if ( config.getProxyInformation() != null )
        {
            HttpHost proxy = new HttpHost( config.getProxyInformation().getProxyHost(), config.getProxyInformation()
                .getProxyPort(), "http" );
            client.getParams().setParameter( ConnRoutePNames.DEFAULT_PROXY, proxy );
        }

        HttpConnectionParams.setConnectionTimeout( httpParams, config == null ? 60000 : config.getConnectionTimeOut() );

        // FIXME 

        //HttpParams params = new BasicHttpParams();
        //params.setParameter( ConnManagerPNames.TIMEOUT, config == null ? 50000 : config
        //.getConnectionPoolTimeOut() );

        //client.setHttpConnectionFactoryTimeout( config == null ? 0 : config.getConnectionPoolTimeOut() );
        return new ApacheHttpClientFourHandler( client, config );
    }

    @Override
    public Providers getProviders()
    {
        Providers providers = super.getProviders();

        return providers;
    }

}
